package com.mk.controller.user;

import cn.hutool.core.bean.BeanUtil;
import com.mk.constant.RedisCacheConstant;
import com.mk.context.BaseContext;
import com.mk.dto.ArticleDTO;
import com.mk.entity.Article;
import com.mk.enumeration.LikedStatusEnum;
import com.mk.result.Result;
import com.mk.service.IArticleService;
import com.mk.utils.RedisUtil;
import com.mk.vo.ArticleVO;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.annotations.Options;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 社区文章相关业务
 */
@RestController
@RequestMapping("/user/article")
@RequiredArgsConstructor
public class ArticleController {

    private final IArticleService articleService;
    private final RedisTemplate redisTemplate;
    private final RedisUtil redisUtil;
    private final HashMap<String, String> hm = new HashMap<>();

    /**
     * 当前用户发布一篇新文章
     * @param articleDTO
     * @return
     */
    @CrossOrigin
    @PostMapping("/publish")
    @Options(keyProperty = "id", useGeneratedKeys = true)
    public Result publishArticle(@RequestBody ArticleDTO articleDTO) {
        Article article = Article.builder()
                .userId(BaseContext.getCurrentId())
                .content(articleDTO.getContent())
                .image(articleDTO.getImage())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        articleService.save(article);

        if (!hm.isEmpty()) hm.clear();
        putArticle(Article.USER_ID, article.getUserId().toString());
        putArticle(Article.CONTENT, article.getContent());
        putArticle(Article.IMAGE, article.getImage());
        putArticle(Article.CREATE_TIME, article.getCreateTime().toString());
        putArticle(Article.UPDATE_TIME, article.getUpdateTime().toString());

        redisUtil.add(RedisCacheConstant.ARTICLE_KEY + article.getId(), hm);

        return Result.success();
    }

    /**
     * 用户根据文章id查看发表的文章信息
     * @param id
     * @return
     */
    @CrossOrigin
    @GetMapping("/getInfo/{id}")
    public Result<ArticleVO> getById(@PathVariable Long id) {
        Map<Object, Object> map = redisUtil.getHashEntries(RedisCacheConstant.ARTICLE_KEY + id);
        if (!map.isEmpty()) {
            Long userId = Long.valueOf(map.get(Article.USER_ID).toString());
            String content = map.get(Article.CONTENT).toString();
            String image = map.get(Article.IMAGE).toString();
            LocalDateTime createTime = LocalDateTime.parse(map.get(Article.CREATE_TIME).toString());
            LocalDateTime updateTime = LocalDateTime.parse(map.get(Article.UPDATE_TIME).toString());

            return Result.success(BeanUtil.copyProperties(
                    Article.builder()
                            .userId(userId)
                            .content(content)
                            .image(image)
                            .createTime(createTime)
                            .updateTime(updateTime)
                            .build(), ArticleVO.class));
        } else {
            Article article = articleService.getById(id);
            return Result.success(BeanUtil.copyProperties(article, ArticleVO.class));
        }
    }

    /**
     * 当前用户删除一篇文章
     * @param id
     * @return
     */
    @CrossOrigin
    @DeleteMapping("/delete/{id}")
    public Result deleteArticle(@PathVariable Long id) {
        Map<Object, Object> map = redisUtil.getHashEntries(RedisCacheConstant.ARTICLE_KEY + id);
        if (!map.isEmpty()) redisUtil.delete(RedisCacheConstant.ARTICLE_KEY + id);
        articleService.removeById(id);
        return Result.success();
    }

    /**
     * 修改文章信息
     * @param article
     * @return
     */
    @PutMapping("/update")
    public Result updateArticle(@RequestBody Article article) {
        article.setUserId(BaseContext.getCurrentId());
        article.setUpdateTime(LocalDateTime.now());
        Map<Object, Object> map = redisUtil.getHashEntries(RedisCacheConstant.ARTICLE_KEY + article.getId());
        if (!map.isEmpty()) {
            String content = map.get(Article.CONTENT).toString();
            String image = map.get(Article.IMAGE).toString();
            LocalDateTime createTime = LocalDateTime.parse(map.get(Article.CREATE_TIME).toString());

            if (article.getContent().isEmpty()) article.setContent(content);
            if (article.getImage().isEmpty()) article.setImage(image);
            article.setCreateTime(createTime);

            redisUtil.delete(RedisCacheConstant.ARTICLE_KEY + article.getId());
            if (!hm.isEmpty()) hm.clear();
            putArticle(Article.USER_ID, article.getUserId().toString());
            putArticle(Article.CONTENT, article.getContent());
            putArticle(Article.IMAGE, article.getImage());
            putArticle(Article.CREATE_TIME, article.getCreateTime().toString());
            putArticle(Article.UPDATE_TIME, article.getUpdateTime().toString());
            redisUtil.add(RedisCacheConstant.ARTICLE_KEY + article.getId(), hm);
        }
        articleService.updateById(article);
        return Result.success();
    }

    /**
     * 点赞文章
     * @param id
     * @return
     */
    @CrossOrigin
    @PostMapping("/like/{id}")
    public Result likeArticle(@PathVariable Long id) {
        StringBuilder sb = new StringBuilder();
        String key = sb.append(id).append("::").append(BaseContext.getCurrentId()).toString();
        if (!hm.isEmpty()) hm.clear();
        putArticle(key, LikedStatusEnum.LIKE.getCode().toString());
        redisUtil.add(RedisCacheConstant.LIKE_ARTICLE_KEY, hm);

        return Result.success();
    }

    /**
     * 取消点赞文章
     * @param id
     * @return
     */
    @CrossOrigin
    @DeleteMapping("/unLike/{id}")
    public Result unLikeArticle(@PathVariable Long id) {
        StringBuilder sb = new StringBuilder();
        String key = sb.append(id).append("::").append(BaseContext.getCurrentId()).toString();
        if (redisUtil.getHashEntries(RedisCacheConstant.LIKE_ARTICLE_KEY).containsKey(key)) {
            redisUtil.delete(RedisCacheConstant.LIKE_ARTICLE_KEY, key);
            return Result.success();
        } else {
            return Result.error("你并未点赞该文章");
        }
    }

    /**
     * 获取文章点赞数
     * @param id
     * @return
     */
    @CrossOrigin
    @GetMapping("/getLikeCount/{id}")
    public Result<Long> getLikeCount(@PathVariable Long id) {
        Article article = articleService.getById(id);
        return Result.success(article.getBeLiked());
    }


    private void putArticle(String key, String value) {
        hm.put(key, value);
    }
}
